import os
import pandas as pd

from data.pandasModel import PandasModel
from utils.define import UNSHOW_INDEX, UNSHOW_DEFAULT
from utils.tools import isdigit, showMessageBox
from datetime import datetime

dirs = ["内账", "外账"]
ITEM_INDEX = ["name", "unit", "num", "unitPrice", "note", "price"]
# basePath = "./"
TITLE_NAMES = ["date", "name", "unit", "num", "unitPrice", "note", "price"]
TITLE_NAMES_CHS = ["日期", "名称及规格", "单位", "数量", "单价", "备注", "金额"]


class CsvManager:
    def __init__(self, controller):
        self.controller = controller
        self.fileDict = {}
        self.initFileDict()
        self._data = None

        # TODO: 检测价格不一致 临时使用
        # from utils.temp_maken2u import make_n2uDict
        # result = make_n2uDict(self.customers, self.fileDict, self.controller.config["specCustomer"])
        # self.controller.config.config["name2UnitPrice"] = result
        # self.controller.config.save_config()
        self.add_year_to_dates()

    @property
    def config(self):
        return self.controller.config

    @property
    def customers(self):
        return self.controller.customers

    @property
    def file_path(self):
        return self.controller.csv_path

    @property
    def customer(self):
        return self.controller.customer

    def getDate(self):
        return self.controller.getDate()

    def getItems(self):
        return self.controller.getItems()

    def getCsvData(self):
        typeDefine = {
            "日期": str,
            "名称及规格": str,
            "单位": str,
            "数量": str,
            "单价": str,
            "备注": str,
            "金额": str,
            "deleted": bool
        }

        try:
            data = pd.read_csv(self.fileDict[self.customer], encoding="utf-8", dtype=typeDefine)
        except UnicodeError:
            data = pd.read_csv(self.fileDict[self.customer], encoding="GBK", dtype=typeDefine)
            data.to_csv(self.fileDict[self.customer], encoding="utf-8", index=False)
            data = pd.read_csv(self.fileDict[self.customer], encoding="utf-8", dtype=typeDefine)
        return data

    def getCsvModel(self):
        if not self.checkFileExist(self.customer):
            return None

        data = self.getCsvData()

        # 之前用于添加 deleted字段
        # reRead = False
        # for key in UNSHOW_INDEX:
        #     if key not in data.columns:
        #         data[key] = UNSHOW_DEFAULT[key]
        #         reRead = True
        #
        # if reRead:
        #     data.to_csv(self.fileDict[self.customer], encoding="utf-8", index=False)
        #     data = getData()

        self._data = data
        controller = PandasModel(self._data)
        controller.dataChanged.connect(self.onDataChanged)
        return controller

    def onDataChanged(self):
        # print("!!! 改变数据", index.row(), index.column())
        self._data.to_csv(self.fileDict[self.customer], encoding="utf-8", index=False)

    def checkFileExist(self, name):
        if name is None or name == "":
            showMessageBox("客户名为空")
            return False
        filePath = self.fileDict.get(name)
        if filePath is None:
            showMessageBox("没有该客户， 请点击新建客户")
            return False
        else:
            return True

    def addCustomer(self, dirName, name):
        try:
            newFilePath = os.path.join(self.file_path, dirName, name + ".csv")
            newFile = pd.DataFrame(columns=TITLE_NAMES_CHS + UNSHOW_INDEX)
            newFile.to_csv(newFilePath, index=False)

            self.fileDict[name] = newFilePath
            return True
        except Exception as e:
            showMessageBox("无法新建文件" + str(e))
            return False

    def save(self, items):
        if len(items) == 0:
            return False

        if not self.checkDataValid(items):
            return False

        if not self.checkFileExist(self.customer):
            return False

        result = []
        # 年.月.日
        date = self.getDate().toString("yyyy.M.dd")
        for item in items:
            rowData = [date]
            for key in ITEM_INDEX:
                rowData.append(item[key])
            for key in UNSHOW_INDEX:
                rowData.append(UNSHOW_DEFAULT[key])
            result.append(rowData)

        newFile = pd.DataFrame(result, columns=TITLE_NAMES_CHS + UNSHOW_INDEX)

        time = datetime.now()
        realDate = str(time.month) + time.strftime(".%d")
        if date != realDate:
            old_data = pd.read_csv(self.fileDict[self.customer], encoding="utf-8")
            combined = pd.concat([old_data, newFile], ignore_index=True)

            # 按日期排序
            combined = combined.sort_values(by="日期", key=lambda x: pd.to_datetime(x, format="%Y.%m.%d"), kind="stable")

            try:
                combined.to_csv(self.fileDict[self.customer], index=False, encoding="utf-8")
                return True
            except PermissionError:
                showMessageBox("请先关闭文件:{}.csv".format(self.customer))
                return False
        else:
            try:
                newFile.to_csv(self.fileDict[self.customer], mode='a', header=False, index=False)
                return True
            except PermissionError:
                showMessageBox("请先关闭文件:{}.csv".format(self.customer))
                return False

    def close(self):
        items = self.getItems()
        if len(items) > 0:
            msg = showMessageBox("数据还未保存，请先保存或清除")
            # if msg:
            #     self.save()
            return False
        return True

    @staticmethod
    def checkDataValid(items):
        def cap(i, ss):
            showMessageBox("第{}行{}".format(i + 1, ss))
            return False

        for index, item in enumerate(items):
            # ["name", "unit", "num", "unitPrice", "note", "price"]
            if item["name"] == "":
                return cap(index, "名字为空")
            if not isdigit(item["num"]):
                return cap(index, "数量错误")
            if not isdigit(item["unitPrice"]):
                return cap(index, "单价格式错误")
            if not isdigit(item["price"]):
                return cap(index, "价格错误")

        return True

    def initFileDict(self):
        for dirName in self.config["customers"].keys():
            dirPath = os.path.join(self.file_path, dirName)
            # 检查并创建 内帐 外帐 文件夹
            if not os.path.exists(dirPath):
                os.mkdir(dirPath)

            for customer in self.config["customers"][dirName]:
                filePath = os.path.join(dirPath, customer + ".csv")
                if not os.path.exists(filePath):
                    self.addCustomer(dirName, customer)
                else:
                    self.fileDict[customer] = filePath

    def add_year_to_dates(self):
        """
        为所有CSV文件中的日期字段添加年份信息
        将"月.日"格式的日期更新为"年.月.日"格式
        """
        # 获取当前农历年份
        current_year = datetime.now().year

        # 遍历所有客户文件
        for customer_name, file_path in self.fileDict.items():
            try:
                # 读取CSV文件
                data = pd.read_csv(file_path, encoding="utf-8", dtype = {
                    "日期": str,
                    "名称及规格": str,
                    "单位": str,
                    "数量": str,
                    "单价": str,
                    "备注": str,
                    "金额": str,
                    "deleted": bool
                })

                # 检查是否存在日期列
                if "日期" in data.columns:
                    # 更新日期格式
                    for i, date_str in enumerate(data["日期"]):
                        if isinstance(date_str, str) and date_str.count('.') == 1:
                            # 如果是"月.日"格式，则添加年份
                            month, day = date_str.split('.')
                            new_date = f"{current_year}.{month}.{day}"
                            data.at[i, "日期"] = new_date

                    # 保存更新后的数据
                    data.to_csv(file_path, index=False, encoding="utf-8")

            except Exception as e:
                print(f"处理文件 {customer_name} 时出错: {e}")
                continue
